package com.zero.demo.jms.service.impl;


import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import com.zero.demo.jms.dao.BaseMapper;
import com.zero.demo.jms.enums.ResultCodeEnum;
import com.zero.demo.jms.service.BaseService;
import com.zero.demo.jms.util.PageResult;
import com.zero.demo.jms.util.PageUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.dao.DataAccessException;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;


/**
 * <p>mybatis通用只读查询的默认实现抽象类 </p>
 *
 * @author yangaj
 * @version V1.0
 * @Package org.cbs.framework.orm
 * @date 2017/9/9 9:36
 */
@Log4j2
public abstract class BaseServiceImpl<T, E, ID extends Serializable> implements BaseService<T, E, ID> {


    public abstract BaseMapper<T, E, ID> getMapper();


    @Override
    public int countByExample(E example) throws Exception {
        try {
            return getMapper().countByExample(example);
        } catch (DataAccessException e) {
            log.error("countByExample_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public T selectByPrimaryKey(ID id) throws Exception {
        try {
            return getMapper().selectByPrimaryKey(id);
        } catch (DataAccessException e) {
            log.error("selectByPrimaryKey_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public List<T> selectByExample(E example) throws Exception {
        try {
            return getMapper().selectByExample(example);
        } catch (DataAccessException e) {
            log.error("selectByExample_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public int updateByExampleSelective(T record, E example) throws Exception {
        try {
            return getMapper().updateByExampleSelective(record, example);
        } catch (DataAccessException e) {
            log.error("updateByExampleSelective_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }


    @Override
    public int updateByExample(T record, E example) throws Exception {
        try {
            return getMapper().updateByExample(record, example);
        } catch (DataAccessException e) {
            log.error("updateByExample_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public int updateByPrimaryKeySelective(T record) throws Exception {
        try {
            return getMapper().updateByPrimaryKeySelective(record);
        } catch (DataAccessException e) {
            log.error("updateByPrimaryKeySelective_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public int updateByPrimaryKey(T record) throws Exception {
        try {
            return getMapper().updateByPrimaryKey(record);
        } catch (DataAccessException e) {
            log.error("updateByPrimaryKey_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public int deleteByExample(E example) throws Exception {
        try {
            return getMapper().deleteByExample(example);
        } catch (DataAccessException e) {
            log.error("deleteByExample_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public int deleteByPrimaryKey(ID id) throws Exception {
        try {
            return getMapper().deleteByPrimaryKey(id);
        } catch (DataAccessException e) {
            log.error("deleteByPrimaryKey_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public int insert(T record) throws Exception {
        try {
            return getMapper().insert(record);
        } catch (DataAccessException e) {
            log.error("insert_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public int insertSelective(T record) throws Exception {
        try {
            return getMapper().insertSelective(record);
        } catch (DataAccessException e) {
            log.error("insertSelective_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    @Override
    public PageResult<List<T>> selectByExamplePage(E example, int pageNum, int pageSize) throws Exception {
        try {
            PageHelper.startPage(pageNum, pageSize, true);
            Page<T> page = (Page)getMapper().selectByExample(example);
            return PageUtils.returnPage(page);
        } catch (DataAccessException e) {
            log.error("selectByExamplePage_" + e.getMessage(), e);
            throw new Exception(ResultCodeEnum.FAILURE.getMsg());
        }
    }

    /**
     * 暂未实现
     * 带text字段的条件查询
     *
     * @param example
     * @return
     * @throws Exception
     */
    @Override
    public List<T> selectByExampleWithBLOBs(E example) throws Exception {
        //TODO
        return null;
    }


    /**
     * 暂未实现
     * 带text字段的条件查询(分页)
     *
     * @param example
     * @return
     * @throws Exception
     */
    @Override
    public List<T> selectByExampleWithBLOBsForStartPage(E example, ID pageNum, ID pageSize) {

        return null;
    }


    /**
     * 暂未实现
     * 带text字段的条件更新
     *
     * @param record
     * @param example
     * @return
     */
    @Override
    public int updateByExampleWithBLOBs(T record, E example) {

        return 0;
    }

    /**
     * 暂未使用
     *
     * @param record
     * @return
     */
    @Override
    public int updateByPrimaryKeyWithBLOBs(T record) throws Exception {

        return 0;
    }


    /**
     * 获取类泛型class
     *
     * @return
     */
    public Class<Mapper> getMapperClass() {
        return (Class<Mapper>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

}